// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'package:json_annotation/json_annotation.dart';
import 'package_api.dart' show UploadInfo;

part 'task_api.g.dart';

/// Response with signed URLs for uploading task results.
///
/// It is important that the [blob] is uploaded before the [index], and that the
/// contents of the index references the given [blobId]. The filename of [index]
/// is static, while the filename of the [blob] is the randomized [blobId].
/// This ensures that if two workers uploading results of the same package, then
/// both will be able to upload the [blob] file, but when they upload the
/// [index] file, one will overwrite the other. Thus, by encoding the [blobId]
/// in [index] we ensure consistency. Using the mismatching [index]/[blob] when
/// reading data is bound to yield garbage.
@JsonSerializable()
class UploadTaskResultResponse {
  /// Identifier for the [blob] file which should be written into the
  /// [index] file.
  final String blobId;

  /// [UploadInfo] for uploading the blob file.
  ///
  /// The blob file is a concatenation of all files generated by the task.
  /// The [index] file will hold an index of filenames and offsets into this
  /// blob. This way we can upload a lot of files in two steps.
  final UploadInfo blob;

  /// [UploadInfo] for uploading the index file for the [blob] file.
  ///
  /// This should embed the [blobId], which points to the [blob] file.
  final UploadInfo index;

  // json_serializable boiler-plate
  UploadTaskResultResponse({
    required this.blobId,
    required this.blob,
    required this.index,
  });
  factory UploadTaskResultResponse.fromJson(Map<String, dynamic> json) =>
      _$UploadTaskResultResponseFromJson(json);
  Map<String, dynamic> toJson() => _$UploadTaskResultResponseToJson(this);
}
